package ro.unibuc.nautilus.controllers;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Vector;

import javax.servlet.http.HttpServletRequest;

import org.springframework.beans.factory.annotation.Required;
import org.springframework.validation.BindException;
import org.springframework.web.bind.ServletRequestDataBinder;
import org.springframework.web.bind.ServletRequestUtils;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.SimpleFormController;

import ro.unibuc.nautilus.controllers.editors.DatePropertyEditor;
import ro.unibuc.nautilus.controllers.editors.EmployeePropertyEditor;
import ro.unibuc.nautilus.domain.Employee;
import ro.unibuc.nautilus.domain.ShipCrewHolder;
import ro.unibuc.nautilus.service.EmployeesService;
import ro.unibuc.nautilus.service.ShipsService;

public class EditShipCrewController extends SimpleFormController {

	private EmployeesService employeeService;
	private ShipsService shipsService;

	public EditShipCrewController() {
	}

	@Override
	protected Object formBackingObject(HttpServletRequest request)
			throws Exception {

		ShipCrewHolder holder = new ShipCrewHolder();
		long shipId = ServletRequestUtils.getLongParameter(request, "shipId",
				-1);

		// Assume create new if argument is missing
		if (shipId == -1) {
			throw new RuntimeException("Can not edit crew on unsaved ship");
		}

		holder.ship = shipsService.findShip(shipId);
		return holder;
	}
	
	private Vector<Employee> getEmployeesWithoutShip() {
		List<Employee> employees = employeeService.findAll();
		
		Vector<Employee> noJobEmployees = new Vector<Employee>();
		
		for (int i = 0; i < employees.size(); i++) {
			Employee empl = employees.get(i);
			
			if (empl.getShip() == null) {
				noJobEmployees.add(empl);
			}
		}
		return noJobEmployees;
	}

	@Override
	protected Map referenceData(HttpServletRequest request) throws Exception {
		Map<Object, Object> model = new HashMap<Object, Object>();
		
		model.put("employees", getEmployeesWithoutShip());
		return model;
	}

	protected void initBinder(HttpServletRequest request,
			ServletRequestDataBinder binder) {

		EmployeePropertyEditor hpe = new EmployeePropertyEditor();
		hpe.setEmployeesService(employeeService);

		binder.registerCustomEditor(Employee.class, hpe);
		binder.registerCustomEditor(Date.class, new DatePropertyEditor());
	}

	@Override
	protected ModelAndView onSubmit(Object command, BindException errors)
			throws Exception {
		ShipCrewHolder holder = (ShipCrewHolder) command;
		//if (holder.isAddCrewMember()) {
			boolean canAdd = true;
			for (Iterator<Employee> it = holder.getCrew().iterator(); it.hasNext();) {
				if (it.next().getId() == holder.getNewMember().getId()) {
					canAdd = false; // member already
					break;
				}
			}
			if (canAdd) {
				holder.getCrew().add(holder.getNewMember());
				shipsService.createOrUpdate(holder.ship);
			}
			Map model = errors.getModel();
			// Repopulate list of employees
			model.put("employees", getEmployeesWithoutShip());

			return new ModelAndView(getFormView(), model);
		//} else {
		//	shipsService.createOrUpdate(holder.ship);
		//	return new ModelAndView(getSuccessView());
		//}
	}

	@Required
	public void setEmployeesService(EmployeesService employeeService) {
		this.employeeService = employeeService;
	}

	@Required
	public void setShipsService(ShipsService shipsService) {
		this.shipsService = shipsService;
	}

}
